package com.beta.backend.gateway.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 * 日期处理工具类
 *
 * @author kevin_zhang
 * @date 2018/7/9
 */
@Slf4j
public class DateUtil {
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private DateUtil(){}

    /**
     * 日期类型转字符串
     *
     * @param date
     * @return
     */
    public static String date2Str(Date date) {
        return date2Str(date, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 日期类型转字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String date2Str(Date date, String format) {
        if (date == null) {
            return "";
        }
        if (StringUtils.isBlank(format)) {
            format = YYYY_MM_DD_HH_MM_SS;
        }
        return new SimpleDateFormat(format, Locale.ENGLISH).format(date);
    }

    /**
     * 字符串转日期类型
     *
     * @param date
     * @param format
     * @return
     */
    public static Date str2Date(String date, String format) {
        DateFormat parser = new SimpleDateFormat(format);
        try {
            return parser.parse(date);
        } catch (ParseException e) {
            log.error("日期转换异常 date = {}, format = {}, 异常 ：{}", date, format, e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取当前时间
     *
     * @param format
     * @return
     */
    public static String currentDate(String format) {
        return new SimpleDateFormat(format).format(currentTime());
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public static Date currentTime() {
        GregorianCalendar calendar = new GregorianCalendar();
        return calendar.getTime();
    }

    /**
     * 指定日期添加N时间(时间可正可负)
     *
     * @param strDate
     * @param format      yyyy-MM-dd HH:mm:ss
     * @param timeType    例：Calendar.YEAR，Calendar.MONTH
     * @param specifyTime
     * @return
     */
    public static String addSpecifyTime(String strDate, String format, int timeType, int specifyTime) {
        if (StringUtils.isBlank(strDate)) {
            return null;
        }
        if (StringUtils.isBlank(format)) {
            format = YYYY_MM_DD_HH_MM_SS;
        }

        Date date = str2Date(strDate, format);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (timeType == Calendar.YEAR || timeType == Calendar.MONTH
                || timeType == Calendar.DATE || timeType == Calendar.HOUR
                || timeType == Calendar.MINUTE || timeType == Calendar.SECOND
                || timeType == Calendar.MILLISECOND) {
            calendar.add(timeType, specifyTime);
        } else {
            return null;
        }
        return date2Str(calendar.getTime(), format);
    }

    public static boolean afterNow(Date curDate, Date compareDate) {
        long curTimes = curDate.getTime();
        long now = compareDate.getTime();
        return curTimes - now > 0;
    }

    /**
     * 获取某天的起始时刻
     *
     * @return
     */
    public static Date startTimeOfDate(Date date) {
        return timeOfDay(date, 0, 0, 0, 0);
    }

    /**
     * 获取今天的中间时刻
     *
     * @return
     */
    public static Date middleTimeOfDate(Date date) {
        return timeOfDay(date, 12, 0, 0, 0);
    }

    /**
     * 获取某天的结束时刻
     *
     * @param date
     * @return
     */
    public static Date endTimeOfDate(Date date) {
        return timeOfDay(date, 23, 59, 59, 999);
    }

    /**
     * 获取某天的指定时间的时刻
     *
     * @param day
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    public static Date timeOfDay(Date day, int hour, int minute, int second, int millisecond) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, millisecond);
        return calendar.getTime();
    }

}
